package com.tiger.weixin.api;

import com.alibaba.fastjson2.JSON;
import com.tiger.weixin.config.WxProperties;
import com.tiger.weixin.dto.AccessToken;
import com.tiger.weixin.dto.UserAccessToken;
import com.tiger.weixin.dto.WxMsgTask;
import com.tiger.weixin.token.AccessTokenContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.HashMap;

/**
 * @Author: spzhang
 * @Date: Created in 16:53 2023/2/20
 * @Description:
 * @Version:
 */
@Slf4j
public abstract class AbstractWxService {
    private RestTemplate weixinRestTemplate;
    private AccessTokenContext context;
    private String sendTempMsg;

    private String grantType;
    private String appid;
    private String secret;
    private String userAuthorized;

    public AbstractWxService(RestTemplate weixinRestTemplate, AccessTokenContext context, WxProperties wxProperties) {
        this.weixinRestTemplate = weixinRestTemplate;
        this.context = context;
        this.sendTempMsg = wxProperties.getUrl().getSendTempMsg();

        this.grantType = wxProperties.getAccessToken().getGrantType();
        this.appid = wxProperties.getAccessToken().getAppid();
        this.secret = wxProperties.getAccessToken().getSecret();
        this.userAuthorized = wxProperties.getUrl().getUserAuthorized();
    }

    /**
     * 发送模板信息
     * @param wxMsgTask
     * @return
     */
    public boolean sendTemplateMsg(WxMsgTask wxMsgTask) {
        String url = sendTempMsg + "?access_token={access_token}";

        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<String> httpEntity = new HttpEntity<>(JSON.toJSONString(wxMsgTask), httpHeaders);
        ResponseEntity<HashMap> responseEntity = weixinRestTemplate.postForEntity(url, httpEntity, HashMap.class, context.getAccessTokenSerial().getAccessToken());
        HttpStatus statusCode = responseEntity.getStatusCode();

        if (statusCode.is2xxSuccessful()) {
            HashMap<String, Object> body = responseEntity.getBody();
            Object errcode = body.get("errcode");
            if (errcode != null && ((Integer)errcode) != 0) {
                log.error("发送模板消息失败，errcode={}，errmsg={}", errcode, body.get("errmsg"));
                return false;
            }
            return true;
        }
        log.error("发送模板消息失败！url:{}, params:{}, headers:{}, responseEntity:{}",
                url, JSON.toJSONString(wxMsgTask), httpHeaders, responseEntity);
        return false;
    }

    public UserAccessToken authorized(String code) {
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("grant_type", "authorization_code");
        params.add("appid", appid);
        params.add("secret", secret);
        params.add("code", code);

        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.TEXT_PLAIN);

        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(userAuthorized).queryParams(params);
        HttpEntity<String> httpEntity = new HttpEntity<>(null, httpHeaders);
        ResponseEntity<String> responseEntity = weixinRestTemplate.exchange(builder.toUriString(), HttpMethod.GET, httpEntity, String.class);
        HttpStatus statusCode = responseEntity.getStatusCode();

        if (statusCode.is2xxSuccessful()) {
            String bodyStr = responseEntity.getBody();
            HashMap<String, Object> body = JSON.parseObject(bodyStr, HashMap.class);
            Object errcode = body.get("errcode");
            if (errcode != null) {
                log.error("获取 user accessToken失败，errcode={}，errmsg={}", errcode, body.get("errmsg"));
                return null;
            }

            UserAccessToken accessToken = new UserAccessToken();
            Object access_token = body.get("access_token");
            Object expires_in = body.get("expires_in");
            Object refresh_token = body.get("refresh_token");
            Object openid = body.get("openid");
            Object scope = body.get("scope");
            Object unionid = body.get("unionid");
            accessToken.setAccessToken((String) access_token);
            accessToken.setExpiresIn((Integer) expires_in);
            accessToken.setRefreshToken((String) refresh_token);
            accessToken.setOpenid((String) openid);
            accessToken.setScope((String) scope);
            accessToken.setUnionid((String) unionid);

            return accessToken;
        }
        log.error("获取accessToken失败！url:{}, params:{}, headers:{}, responseEntity:{}",
                userAuthorized, params, httpHeaders, responseEntity);
        return null;
    }
}
